package com.yilin.tms.order.service.owner.impl;


import com.yilin.commons.util.ArrayUtil;
import com.yilin.commons.util.CommonUtil;
import com.yilin.commons.util.StringUtil;
import com.yilin.tms.core.entity.order.party.ReceiptChangeRecord;
import com.yilin.tms.core.entity.order.payment.OrderPaymentCost;
import com.yilin.tms.core.entity.order.transit.TransitOrder;
import com.yilin.tms.core.entity.user.account.Account;
import com.yilin.tms.core.entity.user.RoleType;
import com.yilin.tms.core.entity.user.UserType;
import com.yilin.tms.order.service.owner.ITransitOwnerService;
import com.yilin.tms.order.service.payment.IOrderPaymentCostService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * 运单前台操作标识
 *
 * @author zhangjinyuan
 * @date 2022/10/29
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class TransitOwnerService implements ITransitOwnerService {

    @Resource
    IOrderPaymentCostService paymentCostService;

    /**
     * 获取前台操作标识
     */
    @Override
    public void getCanOperationMark(Account loginUser, TransitOrder transitOrder, OrderPaymentCost deliveryPaymentCost, OrderPaymentCost receiptPaymentCost, List<ReceiptChangeRecord> receiptChangeRecordList) {
        //是否是我的抢单
        boolean ownerShipper = loginUser.getId().equals(transitOrder.getShipperAccountId());
        boolean ownerTrucker = loginUser.getId().equals(transitOrder.getRobAccountId());
        boolean ownerDriver = loginUser.getId().equals(transitOrder.getTransitTruckUserId());
        transitOrder.setOwner(ownerShipper || ownerTrucker || ownerDriver);

        //运单操作状态
        boolean operateNone = transitOrder.getOperateStatus() == TransitOrder.OperateStatus.none;
        boolean lockingNone = transitOrder.getLockingStatus() == TransitOrder.LockingStatus.none;
        boolean canOpt = operateNone && lockingNone;

        // # >> 公共：置前
        //发货时是否已支付
        transitOrder.setShipperDeliveryPay(canOpt && getShipperDeliveryPay(deliveryPaymentCost));
        //收货时是否已支付
        transitOrder.setShipperReceiptPay(canOpt && getShipperReceiptPay(receiptPaymentCost));

        //是否可以发货时支付
        transitOrder.setShipperDeliveryCanPay(canOpt && ownerShipper && getShipperDeliveryCanPay(transitOrder));
        //是否可以收货时支付
        transitOrder.setShipperReceiptCanPay(canOpt && ownerShipper && getShipperReceiptCanPay(transitOrder));
        //是否可以发货
        transitOrder.setShipperCanDelivery(canOpt && ownerShipper && getShipperCanDelivery(transitOrder));
        //是否可确认回执（货主）
        transitOrder.setShipperCanReceipt(canOpt && ownerShipper && getShipperCanReceipt(transitOrder));
        //是否可以评价
        transitOrder.setShipperCanAppraise(canOpt && ownerShipper && getShipperCanAppraise(transitOrder));

        //是否可以打开装货列表
        transitOrder.setTruckerCanLoading(canOpt && ownerDriver && getTruckerCanLoading(transitOrder));
        //是否可以确认运输
        transitOrder.setTruckerCanTransit(canOpt && ownerDriver && getTruckerCanTransit(transitOrder));
        //是否可以打开卸货列表
        transitOrder.setTruckerCanArriving(canOpt && ownerDriver && getTruckerCanArrive(transitOrder));
        //是否可以暂停运单
        transitOrder.setTruckerCanPausing(operateNone && ownerDriver && getTruckerCanPausing(transitOrder));
        //是否可以换车/换人
        transitOrder.setTruckerCanChange(!operateNone && ownerTrucker && getTruckerCanChange(transitOrder));
        //是否可以恢复运单
        transitOrder.setTruckerCanRecovery(!operateNone && ownerDriver && getTruckerCanRecovery(transitOrder));
        //是否可以强制结束
        transitOrder.setTruckerCanForcedEnd(canOpt && ownerDriver && getTruckerCanForcedEnd(transitOrder));

        //是否可以同意/拒绝更换收货地址
        transitOrder.setTruckerCanAgreeReceiptChange(canOpt &&  ownerDriver && getTruckerCanAgreeReceiptChange(receiptChangeRecordList));

        //是否可以申请仲裁
        transitOrder.setOwnerCanArbitration(transitOrder.getOwner() && getUserCanArbitration(transitOrder));

        //操作提示
        transitOrder.setOptTip(getOptTip(loginUser, transitOrder));
    }

    /**
     * 隐藏运单敏感信息
     */
    @Override
    public void transitOrderPrivateData(TransitOrder transitOrder) {
        //隐藏货主名
        if (StringUtil.isNotEmpty(transitOrder.getShipperAccountName())) {
            transitOrder.setShipperAccountName(StringUtil.privateName(transitOrder.getShipperAccountName()));
        }
        //货主电话
        if (StringUtil.isNotEmpty(transitOrder.getShipperAccountPhone())) {
            transitOrder.setShipperAccountPhone(StringUtil.privatePhone(transitOrder.getShipperAccountPhone()));
        }
        //车主名
        if (StringUtil.isNotEmpty(transitOrder.getRobAccountName())) {
            transitOrder.setRobAccountName(StringUtil.privateName(transitOrder.getRobAccountName()));
        }
        //车主电话
        if (StringUtil.isNotEmpty(transitOrder.getRobAccountPhone())) {
            transitOrder.setRobAccountPhone(StringUtil.privatePhone(transitOrder.getRobAccountPhone()));
        }
    }

    /**
     * 获取运单详情链接
     * 例：http://127.0.0.1:8082/logistics/goods/getGoodsOrderViewDetail.do?goodsOrderId=123
     */
    @Override
    public String getTransitOrderDetailUrl(String transitOrderId) {
        return CommonUtil.getUrl() + "/logistics/rob/getPublicTransitOrderDetail.do?transitOrderId=" + transitOrderId;
    }

    /**
     * 操作提示
     */
    private String getOptTip(Account loginUser, TransitOrder transitOrder) {
        if (loginUser.getUserType() == UserType.shipperUser) {
            if (transitOrder.getLockingStatus() == TransitOrder.LockingStatus.locking) {
                return "订单已锁定，请等待平台仲裁结果";
            }
            if (transitOrder.getOperateStatus() == TransitOrder.OperateStatus.pausing) {
                return "订单已暂停，请等待车主方完成换人/换车操作";
            }
            if (transitOrder.getShipperDeliveryCanPay()){
                return "运单需要发货付款，请及时完成货款支付";
            }
            if (transitOrder.getShipperReceiptCanPay()) {
                return "运单需要到货付款，请及时完成货款支付";
            }
            if (transitOrder.getShipperCanAppraise()) {
                return "运单已完成，请对本次运输作出合理评价";
            }
            if (!transitOrder.getOwner()){
                transitOrderPrivateData(transitOrder);
                return "正在浏览他人运单，如需运输帮助，请仔细阅读“帮助文档";
            }
            return transitOrder.getTransitStatus().shipperTip;
        }
        if (loginUser.getUserType() == UserType.truckerUser) {
            if (transitOrder.getLockingStatus() == TransitOrder.LockingStatus.locking) {
                return "订单已锁定，请等待平台仲裁结果";
            }
            if (transitOrder.getOperateStatus() == TransitOrder.OperateStatus.pausing) {
                if (loginUser.getRoleType() == RoleType.manager)
                    return "订单已暂停，请及时完成换人/换车操作";
                if (loginUser.getRoleType() == RoleType.employee)
                    return "订单已暂停，请等待管理员完成换人/换车操作";
            }
            if (transitOrder.getTransitStatus() == TransitOrder.TransitStatus.waitingTransit && !transitOrder.getShipperDeliveryPay()){
                return "运单需要发货付款，请等待货主方完成支付";
            }
            if (transitOrder.getTransitStatus() == TransitOrder.TransitStatus.waitingReceipt &&!transitOrder.getShipperReceiptPay()) {
                return "运单需要到货付款，请等待货主方完成支付";
            }
            if (!transitOrder.getOwner()){
                transitOrderPrivateData(transitOrder);
                return "正在浏览他人运单，如需接单帮助，请仔细阅读“帮助文档";
            }
            return transitOrder.getTransitStatus().truckerTip;
        }
        return "浏览中，登录货主/车主查看更多详情";
    }


    /**
     * 货主 发货时是否已支付
     */
    private boolean getShipperDeliveryPay(OrderPaymentCost paymentCost) {
        if (paymentCost == null) return false;
        if (paymentCost.getPayStatus() == OrderPaymentCost.PayStatus.none) return true;
        return paymentCost.getPayStatus() == OrderPaymentCost.PayStatus.complete;
    }

    /**
     * 货主 是否可以发货时支付
     */
    private boolean getShipperDeliveryCanPay(TransitOrder transitOrder) {
        if (transitOrder.getTransitStatus() != TransitOrder.TransitStatus.waitingTransit) return false;
        return !transitOrder.getShipperDeliveryPay();
    }

    /**
     * 货主 收货时是否已支付
     */
    private boolean getShipperReceiptPay(OrderPaymentCost paymentCost) {
        if (paymentCost == null) return false;
        if (paymentCost.getPayStatus() == OrderPaymentCost.PayStatus.none) return true;
        return paymentCost.getPayStatus() == OrderPaymentCost.PayStatus.complete;
    }

    /**
     * 货主 是否可以收货时支付
     */
    private boolean getShipperReceiptCanPay(TransitOrder transitOrder) {
        if (transitOrder.getTransitStatus() != TransitOrder.TransitStatus.waitingReceipt) return false;
        return !transitOrder.getShipperReceiptPay();
    }

    /**
     * 货主 是否可以发货
     */
    private boolean getShipperCanDelivery(TransitOrder transitOrder) {
        //判断状态，发货后可以发货支付
        return transitOrder.getTransitStatus() == TransitOrder.TransitStatus.waitingDelivery;
    }

    /**
     * 货主 是否可以确认回执
     */
    private boolean getShipperCanReceipt(TransitOrder transitOrder) {
        if (transitOrder.getTransitStatus() != TransitOrder.TransitStatus.waitingReceipt) return false;
        return !transitOrder.getShipperReceiptCanPay();
    }

    /**
     * 货主 是否可以评价 送达7天内可评价
     */
    private boolean getShipperCanAppraise(TransitOrder transitOrder) {
        if (transitOrder.getTransitStatus() != TransitOrder.TransitStatus.complete) return false;
        if (transitOrder.getReceiptTime() == null) return false;
        return !transitOrder.getAlreadyAppraise();
    }

    /**
     * 司机 是否可以确认Loading
     */
    private boolean getTruckerCanLoading(TransitOrder transitOrder) {
        return transitOrder.getTransitStatus() == TransitOrder.TransitStatus.waitingLoading;
    }

    /**
     * 司机 是否可以确认运输
     */
    private boolean getTruckerCanTransit(TransitOrder transitOrder) {
        if (transitOrder.getTransitStatus() != TransitOrder.TransitStatus.waitingTransit) return false;
        return transitOrder.getShipperDeliveryPay();
    }

    /**
     * 司机 是否可以确认运输
     */
    private boolean getTruckerCanArrive(TransitOrder transitOrder) {
        return transitOrder.getTransitStatus() == TransitOrder.TransitStatus.waitingArrive;
    }

    /**
     * 司机 是否可以申请仲裁
     */
    private boolean getUserCanArbitration(TransitOrder transitOrder) {
        return transitOrder.getTransitStatus() != TransitOrder.TransitStatus.complete
                && transitOrder.getLockingStatus() == TransitOrder.LockingStatus.none;
    }

    /**
     * 司机 是否可以强制结束
     */
    private boolean getTruckerCanForcedEnd(TransitOrder transitOrder) {
        return transitOrder.getOperateStatus() == TransitOrder.OperateStatus.none &&
                transitOrder.getTransitStatus() == TransitOrder.TransitStatus.waitingArrive;
    }

    /**
     * 司机 是否可以暂停运单
     */
    private boolean getTruckerCanPausing(TransitOrder transitOrder) {
        return transitOrder.getTransitStatus().ordinal() < 4
                && transitOrder.getOperateStatus() == TransitOrder.OperateStatus.none;
    }

    /**
     * 司机 是否可恢复运单
     */
    private boolean getTruckerCanRecovery(TransitOrder transitOrder) {
        return transitOrder.getOperateStatus() == TransitOrder.OperateStatus.pausing;
    }

    /***
     * 收货地址改变记录
     * */
    private boolean getTruckerCanAgreeReceiptChange( List<ReceiptChangeRecord> changeRecordList) {
        List<ReceiptChangeRecord> receiptChangeRecords = ArrayUtil.whereBy(changeRecordList, obj -> obj.getChangeState() == ReceiptChangeRecord.ChangeState.applying);
        return receiptChangeRecords.size()>0;
    }

    /**
     * 车主 是否可以换车/换人
     */
    private boolean getTruckerCanChange(TransitOrder transitOrder) {
        return transitOrder.getTransitStatus().ordinal() <= 4
                && transitOrder.getOperateStatus() == TransitOrder.OperateStatus.pausing;

    }
}
